package org.open.sharedRadar;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;

public class RadarFriendsMap extends MapActivity 
{		
    MapView harta = null;
    MyLocationOverlay locatiaMea = null;
    SitesOverlay friendsOverLay = null;
    SitesOverlay radarsOverLay = null;
    Location myLocation = null;
    LocationManager locManager =null;
    LocationListener locListener = null;   
    final DBAdapter myDBAdapter = new DBAdapter(this);
    DecimalFormat df = new DecimalFormat("###.##");
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.map_menu, menu);
	    return true;
		//return super.onCreateOptionsMenu(menu);
	}
    
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.showFriends:
	    	showRemoveFriends();
	        return true;
	    case R.id.showRadars:
	    	showRemoveRadars();
	        return true;	    
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	@Override
	public void onPause(){
		super.onPause();
		locManager.removeUpdates(locListener);
		locatiaMea.disableMyLocation();
	}
	@Override
	protected boolean isLocationDisplayed() {		
		return locatiaMea.isMyLocationEnabled();
	}

	@Override
	protected boolean isRouteDisplayed() {		
		return true;		
	}
	@Override
	public void onResume(){
		super.onResume();
		Location ultimaLocatieCunoscuta = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
		this.myLocation = ultimaLocatieCunoscuta;
		afiseazaLocatie(ultimaLocatieCunoscuta);
		
		locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
		
		locatiaMea.enableMyLocation();
		locatiaMea.runOnFirstFix(new Runnable(){
			public void run(){
				harta.getController().setCenter(locatiaMea.getMyLocation());
				showRemoveRadars();				
			}
		});
	}		
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.radarfriendsmap);
        harta = (MapView) findViewById(R.id.harta);
        
        harta.setBuiltInZoomControls(true);
        //harta.getController().setCenter(new GeoPoint((int) (47.157109 * 1E6), (int) (27.588329 * 1E6)));
        harta.getController().setZoom(15);
        locatiaMea = new MyLocationOverlay(this, harta);
        harta.getOverlays().add(locatiaMea);       
        harta.postInvalidate();
        Button btnReportRadarFix =(Button) findViewById(R.id.btnReportRadarFix); 
        btnReportRadarFix.setOnClickListener(new OnClickListener(){
        	
        	public void onClick(View v){
        		reportRadar(true,false);
        	}
        });
        Button btnReportRadarMobil =(Button) findViewById(R.id.btnReportRadarMobil); 
        btnReportRadarMobil.setOnClickListener(new OnClickListener(){
        	
        	public void onClick(View v){
        		reportRadar(false,false);
        	}
        });
        Button btnReportRadarErr =(Button) findViewById(R.id.btnReportRadarErr); 
        btnReportRadarErr.setOnClickListener(new OnClickListener(){
        	
        	public void onClick(View v){
        		reportRadar(true,true);
        	}
        });
        locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        
        locListener = new LocationListener(){
        	public void onLocationChanged(Location location){
        		afiseazaLocatie(location); 
        		afiseazaWarningRadarAproape(location);
        	}
        	
        	public void onProviderDisabled(String provider){
        		
        	}
        	public void onProviderEnabled(String provider){
        		
        	}
        	
        	public void onStatusChanged(String provider, int status, Bundle extras){
        		
        	}
        };
    }
	private void afiseazaLocatie(Location locatie){
		if (locatie != null){
			double lat = locatie.getLatitude();
			double lng = locatie.getLongitude();
			GeoPoint pctLocatie = Radar.getPoint(lng, lat);	
			/*
			WebServiceHandler handler = new WebServiceHandler();
			handler.updateLocation();
			*/
			//Toast.makeText(getBaseContext(), "Noua locatie: lat [" + lat + "] long [" + lng + "]", Toast.LENGTH_SHORT).show();
			harta.getController().animateTo(pctLocatie);
			myLocation = locatie;
    		CurentUserProperties.getInstance().myCurrentLocation = myLocation;
			
		}
	}	
	private void afiseazaWarningRadarAproape(Location locatie) {
   		if (locatie != null){
			double lat = locatie.getLatitude();
			double lng = locatie.getLongitude();
			boolean radarAproape = false;
			myDBAdapter.open();
			myDBAdapter.synchronizeLocationsWithWeb();			 
			Cursor lista = null;			  
			lista = myDBAdapter.getLocationsFromDB(true);	    	  
			lista.moveToFirst();
			
			while (lista.isAfterLast() == false) {				
   			   	Double lngR = Double.parseDouble(lista.getString(1));
   			   	Double latR = Double.parseDouble(lista.getString(2));	   			   
   			   	Double dist = calculateHaversineDistanceBetweenPoints(lat,lng, latR, lngR);    			   	
   			   	if (dist <= 1)
   			   	{
   			   		String distStr = df.format(dist);
   			   		Toast.makeText(getApplicationContext(), "Atentie! Un radar la o distanta de: " + distStr + " km !", Toast.LENGTH_LONG).show();
   			   		break;
   			   	}
   			   	
   			   	lista.moveToNext();
			}
			lista.close();
			myDBAdapter.close();
    	  	    	 

			myLocation = locatie;
    		CurentUserProperties.getInstance().myCurrentLocation = myLocation;
			
		}	
	}
	public double calculateHaversineDistanceBetweenPoints(double lat1_, double lng1_, double lat2_, double lng2_){			
    	double earthRadius = 6371;//km
	    double dLat = Math.toRadians(lat2_-lat1_);
	    double dLng = Math.toRadians(lng2_-lng1_);
	    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
	               Math.cos(Math.toRadians(lat1_)) * Math.cos(Math.toRadians(lat2_)) *
	               Math.sin(dLng/2) * Math.sin(dLng/2);
	    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
	    double dist = earthRadius * c;

	    return dist;
	}

	protected void reportRadar(Boolean fix_, Boolean inexistent_)
	{
		WebServiceHandler handler = new WebServiceHandler();
		String message = handler.reportRadar(fix_,inexistent_);
		Toast.makeText(getBaseContext(), message, Toast.LENGTH_SHORT).show();
		showRemoveRadars();
		showRemoveRadars();
	}	

	protected void showRemoveFriends()
	{
		if(friendsOverLay != null)
		{
			harta.getOverlays().remove(friendsOverLay);
			friendsOverLay = null;
		}
		else
		{
			Drawable friend = getResources().getDrawable(R.drawable.icon_small);
	        
			friend.setBounds(0, 0, friend.getIntrinsicWidth(),
					friend.getIntrinsicHeight());
			friendsOverLay = new SitesOverlay(friend, false);
	        harta.getOverlays().add(friendsOverLay);
		}
		afiseazaLocatie(this.myLocation);
	}	
	
	protected void showRemoveRadars()
	{
		if(radarsOverLay != null)
		{
			harta.getOverlays().remove(radarsOverLay);
			radarsOverLay = null;
		}
		else
		{
			Drawable radar = getResources().getDrawable(R.drawable.ic_police);
	        
			radar.setBounds(0, 0, radar.getIntrinsicWidth(),
					radar.getIntrinsicHeight());			
			radarsOverLay = new SitesOverlay(radar, true);
	        harta.getOverlays().add(radarsOverLay);
		}
		afiseazaLocatie(this.myLocation);
	}			
	
	private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
	    private List<OverlayItem> items=new ArrayList<OverlayItem>();
	    
	    public SitesOverlay(Drawable marker, Boolean radars_) {
	      super(marker);	     
	      boundCenterBottom(marker);	        
	      
	      if(myLocation != null)
	      {	    	   	 
	    	  myDBAdapter.open();
			  myDBAdapter.synchronizeLocationsWithWeb();			 
			  Cursor lista = null;			  
	    	  lista = myDBAdapter.getLocationsFromDB(radars_);	    	  
	    	  lista.moveToFirst();
	          while (lista.isAfterLast() == false) {
	        	  String tipRadar = lista.getString(0);
	   			   Double lon = Double.parseDouble(lista.getString(1));
	   			   Double lat = Double.parseDouble(lista.getString(2));	   			   
	   			   items.add(new OverlayItem(Radar.getPoint(lon,lat),
	   					tipRadar, tipRadar));	 	        	  	        	 
	              lista.moveToNext();
	          }
	          lista.close();
	          myDBAdapter.close();
	    	  	    	 
	      }	      
	      populate();
	    }
	    
	    @Override
	    protected OverlayItem createItem(int i) {
	      return(items.get(i));
	    }
	    
	    @Override
	    protected boolean onTap(int i) {
	      Toast.makeText(RadarFriendsMap.this,
	                      items.get(i).getSnippet(),
	                      Toast.LENGTH_SHORT).show();
	      
	      return(true);
	    }
	    
	    @Override
	    public int size() {
	      return(items.size());
	    }
	  }			
}